package top.yangguangmc.sunshine_anticheat.check.checks.player;

import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import top.yangguangmc.sunshine_anticheat.check.Check;
import top.yangguangmc.sunshine_anticheat.check.CheckCategory;
import top.yangguangmc.sunshine_anticheat.check.CheckSetting;
import top.yangguangmc.sunshine_anticheat.utils.Timer;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

public class EagleCheck extends Check {
    private final Map<Player, Object[]> beCheckedPlayers = new HashMap<>();

    @CheckSetting(configName = "threshold")
    private int thresholdTicks = 8;

    public EagleCheck() {
        super("Eagle", "eagle", CheckCategory.PLAYER);
    }

    @EventHandler
    public void onBlockPlace(BlockPlaceEvent event) {
        if (validateCheckable(event.getPlayer())) {
            Player player = event.getPlayer();
            if (player.isSneaking()) {
                Object[] objects = beCheckedPlayers.get(player);
                if (objects != null && ((Timer) objects[0]).hasTimePassed(10000)) {
                    beCheckedPlayers.remove(player);
                    return;
                }
                beCheckedPlayers.put(player, new Object[]{new Timer(), new LinkedList<Long>()});
            }
        }
    }

    @SuppressWarnings("unchecked")
    @EventHandler
    public void onPlayerSneak(PlayerToggleSneakEvent event) {
        if (isEnabled()) {
            Object[] objects = beCheckedPlayers.get(event.getPlayer());
            if (objects != null) {
                LinkedList<Long> timeStamps = (LinkedList<Long>) objects[1];
                timeStamps.addFirst(System.currentTimeMillis());
                if (timeStamps.size() > 6) {
                    long duration1 = timeStamps.get(1) - timeStamps.get(0);
                    long duration2 = timeStamps.get(3) - timeStamps.get(2);
                    long duration3 = timeStamps.get(5) - timeStamps.get(4);
                    if (isInRange(duration1, duration2, duration3))
                        failCheck(event.getPlayer(), 1, "Bridges too regularly.");
                    timeStamps.removeLast();
                }
            }
        }
    }

    private boolean isInRange(long... numbers) {
        long sum = 0;
        for (long num : numbers) {
            sum += num;
        }
        long center = sum / numbers.length;
        long max = center + thresholdTicks;
        long min = center - thresholdTicks;

        boolean result = true;
        for (long num : numbers) {
            if (num < min || num > max) {
                result = false;
                break;
            }
        }
        return result;
    }
}
